class GameMap {
    data = []
    /**
     * @param {*} id 地图唯一标识
     * @param {*} x 列数
     * @param {*} y 行数
     * @param {*} offsetRate 偏移比例
     * @param {*} picNum 图片总类数
     * @param {*} count 每种图片有几组
     */
    constructor(id, x, y, offsetRate, picNum, count, blockSize) {
        if (!x || !y) throw new Error('未指定地图参数')
        this.BlockSize = blockSize
        this.id = id
        this.offset = offsetRate * this.BlockSize
        this.rows = offsetRate == 0 ? y / this.BlockSize : (y - this.offset) / this.BlockSize
        this.columns = offsetRate == 0 ? x / this.BlockSize : (x - this.offset) / this.BlockSize
        if (this.rows * this.columns < count * 3 * 3) throw new Error('物品数量大于地图格数')
        this.initMapData()
        const mapData = Utils.randomMapData(this.rows, this.columns, picNum, count * 3)
        mapData.forEach(item => {
            this.data[item.x][item.y].type = item.img
        })
    }
    initMapData() {
        for (let i = 0; i < this.rows; i++) {
            this.data.push([])
            for (let j = 0; j < this.columns; j++) {
                this.data[i][j] = {
                    type: null
                }
            }
        }
    }
    reset() {
        this.data.forEach(row => {
            row.forEach(column => {
                column = null
            })
        })
        this.draw()
    }
    update({ indexX, indexY }, value) {
        this.data[indexX][indexY].type = value
        // this.draw()
    }
    isEmptyMap() {
        let isEmpty = true
        this.data.forEach(row => {
            row.forEach(column => {
                if (column && column.type) isEmpty = false
            })
        })
        return isEmpty
    }
    arr2Map(mapArr) {
        if (!mapArr) return
        mapArr.forEach(item => {
            this.data[item.x][item.y] = item.img
        })
    }
    draw() {
        this.data.forEach((column, columnIndex) => {
            column.forEach((row, rowIndex) => {
                if (!row.type) {
                    return
                }
                const dx = rowIndex * this.BlockSize + this.offset / 2
                const dy = columnIndex * this.BlockSize + this.offset / 2
                ctx.drawImage(Images[row.type - 1], dx, dy, this.BlockSize, this.BlockSize)
            })
        })
    }
    clear() {
        ctx.clearRect(0, 0, CanvasWidth, CanvasHeight)
    }
    coordinate2Index(x, y) {
        return {
            indexX: parseInt((x - this.offset / 2) / this.BlockSize),
            indexY: parseInt((y - this.offset / 2) / this.BlockSize)
        }
    }
    isInMap(x, y) {
        if (
            x - this.offset / 2 < 0 ||
            y - this.offset / 2 < 0 ||
            x > CanvasWidth - this.offset / 2 ||
            y > CanvasHeight - this.offset / 2
        ) {
            return
        }
        const { indexX, indexY } = this.coordinate2Index(x, y)
        console.log(indexX, indexY)
        let value
        if ((value = this.data[indexX][indexY]) && value.type) {
            const mapName = parseInt(this.id.replace(/[a-z]/g, ''))
            // 获取中心点的世界坐标
            const worldCoordinateX = indexX * this.BlockSize + this.offset / 2 + this.BlockSize / 2
            const worldCoordinateY = indexY * this.BlockSize + this.offset / 2 + this.BlockSize / 2
            const result = {
                map: this,
                payload: { type: value.type },
                index: mapName,
                origincoordinate: {
                    indexX,
                    indexY
                },
                // 返回四个顶点的世界坐标
                coordinate: {
                    1: `${worldCoordinateX - this.BlockSize / 2},${
                        worldCoordinateY - this.BlockSize / 2
                    }`,
                    2: `${worldCoordinateX - this.BlockSize / 2},${
                        worldCoordinateY + this.BlockSize / 2
                    }`,
                    3: `${worldCoordinateX + this.BlockSize / 2},${
                        worldCoordinateY - this.BlockSize / 2
                    }`,
                    4: `${worldCoordinateX + this.BlockSize / 2},${
                        worldCoordinateY + this.BlockSize / 2
                    }`
                }
            }
            return result
        }
        return null
    }
    hasOverBlock(hit) {
        // 获取四个块
        let hasOverBlock = false
        for (let i = 1; i <= 4; i++) {
            const tempX = hit.coordinate[i].split(',')[0]
            const tempY = hit.coordinate[i].split(',')[1]
            const { indexX, indexY } = this.coordinate2Index(tempX, tempY)
            if (indexX < 0 || indexY < 0 || indexX >= this.rows || indexY >= this.columns) break
            if (this.data[indexX][indexY].type && this.data[indexX][indexY].type) {
                hasOverBlock = true
            }
        }
        return hasOverBlock
    }
}

// 底部缓冲队列
class Queue {
    constructor(length) {
        this.length = length
        this.data = []
    }
    push(item) {
        this.data.push(item)
    }
    processQueueData() {
        const keyMap = new Map()
        this.data.forEach(({ source }) => {
            if (keyMap.has(source.type)) keyMap.set(source.type, keyMap.get(source.type) + 1)
            else keyMap.set(source.type, 1)
        })
        for (const key of keyMap.keys()) {
            if (keyMap.get(key) >= 3) {
                const reset = this.data.filter(item => item.source.type != key)
                this.data.splice(0, 7)
                this.data.push(...reset)
            }
        }
    }
    isFull() {
        this.processQueueData()
        this.updateDom()
        return this.data.length == this.length
    }
    isEmpty() {
        this.processQueueData()
        this.updateDom()
        return this.data.length == 0
    }
    // 更新队列
    updateDom() {
        // 遍历全部处理, 这部分需要优化, 频繁操作DOM
        for (let i = 0; i < this.length; i++) {
            const queueObj = this.data[i]
            const box = document.getElementsByClassName('queue')[0].children[i]
            box.innerHTML = ''
            if (queueObj && queueObj.source.type) {
                // 清除DOM
                const img = document.createElement('img')
                img.src = 'imgs/' + this.data[i].source.type + '.png'
                img.style.height = '60px'

                // 遮罩层
                const cover = document.createElement('img')
                cover.src = 'imgs/cover.png'
                cover.className = 'cover-image'

                box.appendChild(img)
                box.appendChild(cover)
            }
        }
    }
}
